-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
modules: runtime deprecate module.parent #33534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Didn't the documentation deprecation for this just land the other day? Do we really need to do a runtime deprecation that quickly? |
This PR won't land until v15 at the soonest (which is due for October), and it can also be blocked until v16 or later if we think it's too soon. |
8ae28ff
to
2935f72
Compare
lib/internal/modules/cjs/loader.js
Outdated
getModuleParent.warned = true; | ||
} | ||
if (parent === undefined) { | ||
return new (class UnknownModule {})(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this new class instance instead of keeping the return value the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should probably at least be cached if it’s truly necessary, otherwise it breaks the expectation that module.parent === module.parent
.
I'm not sure if it's worth keep working on this: it's been open for a few months at this point: we haven't received any bug ticket complaining about |
@aduh95 i suspect that's more likely due to the (expectedly) slow adoption curve of native ESM. |
b030017
to
049057e
Compare
049057e
to
df3b47f
Compare
@aduh95 can you elaborate on why "UnknownModule" is needed? |
The idea is to return a truthy value, it could be something else. I'm open to better suggestions 😅 The reason I'd like it to be truthy is to cover the case where a package author has written test code like this: if(!module.parent) { /* test code with potential side effects here */ } Currently this runs the test code when the module is |
Sure, but don't we want that code to continue to fail, since |
Depends what you mean by "continue to fail", currently it doesn't really fail: the test code is being executed on a production environment, which may or may not introduce unwanted side effects – it could as harmless as printing I think we should keep in mind that keeping That being said, if the consensus is to keep the current behaviour and simply add the runtime warning, I'll update the PR. |
Fair - tbh tho this seems like two separate PRs, and it might be useful to land/review/discuss them separately. |
Fair, I've opened #37702 for the |
I have found that a very popular module accesses |
They shouldn't be impacted, the runtime warning is emitted only if the module is loaded from ESM or REPL (when |
I understand. I just wanted to add this somewhere si it's taken into account. Is there a better issue/PR where I can post that message? |
It was discussed originally in nodejs/modules#469, so maybe there? |
@aduh95 Will you be rebasing this on |
Unlikely to ever happen, we can keep it as doc-deprecated. |
TL;DR: runtime warning when this
module.parent
is accessed from a module that have a nullish value for theirmodule.parent
(when a ESM imports it or when the module is run as the entry point of the process).Currently,
module.parent
provides a way for CJS users to get which CJS modules required the current module first. This feature – not very useful by itself – is also used to make assumption about the program entry point. It is not rare to find packages that wrap their test code inside aif(!module.parent)
condition, assuming that a falsy value means the module is run from CLI. The issue with this pattern is that the assumption doesn't work as soon as the module interacts with ESM or REPL.With ESM being unflagged in current and LTS release lines, I predict this could become a real pain point for users trying to use ESM in Node.js.
Current issue
The issue I'd like to address is when a dependency is using the
if(!module.parent)
pattern to run its tests, and the test code gets executed for ESM users without their knowledge; those tests that may have side effects and make the end user code fail without obvious reason.Action taken in this PR
setthat was moved to module: make module.parent truthy when loaded from ESM #37702.module.parent
to a truthy value instead ofundefined
(in this PR, I'm using a dummy classUnknownModule
).module.parent
is nullish, so it warns:Objections and alternative solutions
UnknownModule
object created is effectively just an empty object, it doesn't have any property of the module object users may expect.If this is not acceptable, we can keep the current behaviour (
module.parent
isundefined
if the module was loaded by something that is not a CommonJS module).if(!module.parent)
pattern in their CLI exposed file. That would lead to end users seeing a warning they have no control over. I don't think there would be a lot of packages affected by this, but that's a possibility.If this is not acceptable, we can check if the file is inside a
node_modules
folder (similarly to what we do forBuffer
constructor), or stick to the doc only deprecation for the time being.Refs: #32217
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes